package gov.pbc.nn.core.aspect;

import javax.servlet.http.HttpServletRequest;

import org.apache.log4j.MDC;
import org.aspectj.lang.JoinPoint;
import org.aspectj.lang.annotation.Aspect;
import org.aspectj.lang.annotation.Before;
import org.springframework.beans.BeansException;
import org.springframework.context.ApplicationContext;
import org.springframework.context.ApplicationContextAware;
import org.springframework.stereotype.Component;

import com.bstek.bdf2.core.business.IUser;
import com.bstek.bdf2.core.context.ContextHolder;
import com.bstek.dorado.annotation.DataProvider;
import com.bstek.dorado.annotation.DataResolver;
import com.bstek.dorado.annotation.Expose;
import com.bstek.dorado.uploader.annotation.FileProvider;
import com.bstek.dorado.uploader.annotation.FileResolver;

@Aspect
@Component
public class LogAspect implements ApplicationContextAware {

	@Before("@annotation(dataProvider)")
	public void doBefore(JoinPoint joinPoint, DataProvider dataProvider)
			throws Throwable {
		setMDC(joinPoint);
	}

	@Before("@annotation(dataResolver)")
	public void doBefore(JoinPoint joinPoint, DataResolver dataResolver)
			throws Throwable {
		setMDC(joinPoint);
	}

	@Before("@annotation(fileProvider)")
	public void doBefore(JoinPoint joinPoint, FileProvider fileProvider)
			throws Throwable {
		setMDC(joinPoint);
	}

	@Before("@annotation(fileResolver)")
	public void doBefore(JoinPoint joinPoint, FileResolver fileResolver)
			throws Throwable {
		setMDC(joinPoint);
	}

	@Before("@annotation(expose)")
	public void doBefore(JoinPoint joinPoint, Expose expose) throws Throwable {
		setMDC(joinPoint);
	}

	@Override
	public void setApplicationContext(ApplicationContext applicationContext)
			throws BeansException {
	}

	private static void setMDC(JoinPoint joinPoint) {
		IUser user = ContextHolder.getLoginUser();
		MDC.put("username",
				user == null ? "匿名" : (user.getCname() + "("
						+ user.getUsername() + ")"));
		MDC.put("method", joinPoint.getSignature());
		MDC.put("ip", getRemoteHost(ContextHolder.getRequest()));
	}

	private static String getRemoteHost(HttpServletRequest request) {
		String ip = request.getHeader("x-forwarded-for");
		if (ip == null || ip.length() == 0 || "unknown".equalsIgnoreCase(ip)) {
			ip = request.getHeader("Proxy-Client-IP");
		}
		if (ip == null || ip.length() == 0 || "unknown".equalsIgnoreCase(ip)) {
			ip = request.getHeader("WL-Proxy-Client-IP");
		}
		if (ip == null || ip.length() == 0 || "unknown".equalsIgnoreCase(ip)) {
			ip = request.getRemoteAddr();
		}
		return ip.equals("0:0:0:0:0:0:0:1") ? "127.0.0.1" : ip;
	}
}
